package org.hs.phd.common.simpleplayer.frameviewer;

import java.awt.BorderLayout;
import java.awt.Point;
import java.awt.Polygon;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;

import org.hs.phd.common.simpleplayer.FramViewerController;
import org.hs.phd.common.simpleplayer.FramePlayer;
import org.hs.phd.common.simpleplayer.ImageSequenceFrame;
import org.hs.phd.common.simpleplayer.PlayerEvent;
import org.hs.phd.common.simpleplayer.PlayerViewerLayer;

public class DefaultFrameViewerImpl implements FrameViewer, FrameViewerTransformation, FramViewerController {


	private ViewerCanvas viewerCanvas;
	private JPanel ui;
	private List<PlayerViewerLayer> layers;
	private final FramePlayer player;

	public DefaultFrameViewerImpl(FramePlayer player){
		this.player = player;
		viewerCanvas = new ViewerCanvas(this);
		ui = new JPanel(new BorderLayout());
		constructGUI();
        layers = new ArrayList<PlayerViewerLayer>();
	}
	
	private void constructGUI() {
		JScrollPane jScrollPane = new JScrollPane(viewerCanvas);
		
		DefaultController controller = new DefaultController(player);
		
		ui.add(jScrollPane, BorderLayout.CENTER);
		ui.add(controller.getUI(), BorderLayout.SOUTH);
	}

	/* (non-Javadoc)
	 * @see org.hs.phd.common.frameviewer.FrameViewer#getUI()
	 */
	@Override
	public JComponent getUI() {
		return ui;
	}

	/* (non-Javadoc)
	 * @see org.hs.phd.common.frameviewer.FrameViewer#setImage(com.googlecode.javacv.cpp.opencv_core.IplImage)
	 */
	/* (non-Javadoc)
	 * @see org.hs.phd.common.frameviewer.FrameViewer#repaint()
	 */
	@Override
	public void repaint() {
		viewerCanvas.repaint();
	}

	/* (non-Javadoc)
	 * @see org.hs.phd.common.frameviewer.FrameViewer#zoomIn()
	 */
	@Override
	public void zoomIn() {
		viewerCanvas.setScale( viewerCanvas.getScale() * 2.0F );
	}

	/* (non-Javadoc)
	 * @see org.hs.phd.common.frameviewer.FrameViewer#zoomOut()
	 */
	@Override
	public void zoomOut() {
		viewerCanvas.setScale( viewerCanvas.getScale() / 2.0F );
	}

	/* (non-Javadoc)
	 * @see org.hs.phd.common.frameviewer.FrameViewer#viewToModel(int, int)
	 */
	@Override
	public Point viewToModel(int x, int y) {
		return viewerCanvas.viewToModel(x, y);
	}

	/* (non-Javadoc)
	 * @see org.hs.phd.common.frameviewer.FrameViewer#modelToView(int, int)
	 */
	@Override
	public Point modelToView(int x, int y) {
		return viewerCanvas.modelToView(x, y);
	}

	/* (non-Javadoc)
	 * @see org.hs.phd.common.frameviewer.FrameViewer#modelToView(java.awt.Polygon)
	 */
	@Override
	public Polygon modelToView(Polygon polygon) {
		Polygon result = new Polygon();
		
		for(int i = 0; i < polygon.npoints; i++){
			Point p = modelToView(polygon.xpoints[i], polygon.ypoints[i]);
			result.addPoint(p.x, p.y);
		}
		return result;
	}

	/* (non-Javadoc)
	 * @see org.hs.phd.common.frameviewer.FrameViewer#viewToModel(java.awt.Polygon)
	 */
	@Override
	public Polygon viewToModel(Polygon polygon) {
		Polygon result = new Polygon();
		
		for(int i = 0; i < polygon.npoints; i++){
			Point p = viewToModel(polygon.xpoints[i], polygon.ypoints[i]);
			result.addPoint(p.x, p.y);
		}
		return result;
	}

	/* (non-Javadoc)
	 * @see org.hs.phd.common.frameviewer.FrameViewer#setScale(float)
	 */
	@Override
	public void setScale(float scale) {
		viewerCanvas.setScale(scale);
	}

	/* (non-Javadoc)
	 * @see org.hs.phd.common.frameviewer.FrameViewer#getScale()
	 */
	@Override
	public float getScale(){
		return viewerCanvas.getScale();
	}

	@Override
	public FrameViewerTransformation getTransformation() {
		return this;
	}

	@Override
	public void show(final ImageSequenceFrame frame) {
		
		
//		try {
			SwingUtilities.invokeLater(new Runnable() {
				
				@Override
				public void run() {
					viewerCanvas.setImage(frame);
				}
			});
//		} catch (InterruptedException e) {
//			//do nothing
//		} catch (InvocationTargetException e) {
//			e.printStackTrace();
//		}
	}
	

	@Override
	public void addViewerLayer(PlayerViewerLayer layer) {
		layers.add(layer);
		layer.setViewer(this);
		viewerCanvas.addLayer(layer);
	}

	@Override
	public FramViewerController getViewerController() {
		return this;
	}

	@Override
	public void fireEvent(PlayerEvent event) {
		player.fireEvent(event);
	}

	@Override
	public FramePlayer getPlayer() {
		return player;
	}

}
